<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        ul{
            width: 500px;
            height: 400px;
            background: gold;
        }
    </style>
</head>
<body>
    <div id="divOne" onclick="alert('我是最外层')" >
    <div id="divTwo" onclick="alert('我是最中层')">
        <div id="divthree" onclick="alert('我是里层')"></div>
    </div>
    </div>

    <ul class="list-group">
        <li class="list-group-item">Item 1</li>
        <li class="list-group-item">Item 2</li>
        <li class="list-group-item">Item 3</li>
        <li class="list-group-item">Item 4</li>
        <li class="list-group-item">Item 5</li>
        <li class="list-group-item">Item 6</li>
    </ul>  
</body>
</html>
<script>
    //事件冒泡。
      //子集元素的某个事件被触发，它的上级元素的该事件也被递归触发
    //事件委托。
      //使用事件冒泡的原理，从触发某个事件的元素开始，递归向上级元素传播事件
    //事件委托优点。
      //对于套处理的大量元素，不必每个元素都绑定事件，只需要在他们的父元素上绑定一次即可，提高性能
      //可以处理动态插入dom中的元素，对动态插入dom中的元素进行绑定是不行的 

    // 事件委托给父元素后，如何知道事件是那一个子元素触发的? 
      //可以通过event.target对象获取   
    
    // target和currentTarget区别
      //event.target        返回触发事件的元素
      //event.currentTarget 返回绑定事件的元素


      /*
    事件委托 本质上是利用了浏览器事件冒泡的机制。因为事件在冒泡过程中会上传到父节点，
    并且父节点可以通过事件对象获取到 目标节点，因此可以把子节点的监听函数定义在父节点上，由父节点的监听函数统一处理多个子元素的事件，这种方式称为事件代理。
    使用事件代理我们可以不必要为每一个子元素都绑定一个监听事件，这样减少了内存上的消耗。
    并且使用事件代理我们还可以实现事件的动态绑定，比如说新增了一个子节点，我们并不需要单独地为它添加一个监听事件，它所发生的事件会交给父元素中的监听函数来处理。     
    */

    
//____________________________________________________________________________________-
    //阻止事件冒泡
        //js中的
           //依次弹出里 中 外 出现了事件冒泡
                //<div id="divOne" onclick="alert('我是最外层')" >
                // <div id="divTwo" onclick="alert('我是最中层')">
                //     <div id="divthree" onclick="alert('我是里层')"></div>
                // </div>
                // </div> 
          //js 
                //document.getElementById("XXX").onclick=funciton(event){
                //    event.stopPropagation(); 阻止事件冒泡 不会阻止默认行为 
                //}
                //    return false             自己都阻止了，只提示中间和外层
                //    event.preventDefault()   自己都阻止了，只提示中间和外层    



//__________________________________________________________________________________________________________________________________    
    //在页面上10li添加监听 点谁谁变红 
        // var lis = document.getElementsByTagName('li')
        // for (let i = 0; i< lis.length; i++) {
        //     lis[i].onclick =function(){
        //         // alert(i)
        //         this.style.background = 'red'
        //     }
        // }s
    //方法2.事件委托 委托给父级 利用事件冒泡
    //e.target 是一个 对象
    var uls = document.querySelector('ul')
    uls.onclick= function(e){
        // e.target.style.background = "red"
        console.log(e)
        if(e.target.nodeName === 'LI'){
            e.target.style.background = "red"
        }
    }
//_______________________________________________________________________________________________________________________________________
    // 事件委托利用了事件冒泡，只指定一个事件处理程序，就可以管理某一类型的所有事件。
    // 所有用到按钮的事件（多数鼠标事件和键盘事件）都适合采用事件委托技术，使用事件委托可以节省内存。

    // <ul>
    //   <li>苹果</li>
    //   <li>香蕉</li>
    //   <li>凤梨</li>
    // </ul>

    // good
    // document.querySelector('ul').onclick = (event) => {
    //   let target = event.target
    //   if (target.nodeName === 'LI') {
    //     console.log(target.innerHTML)
    //   }
    // }

    // // bad
    // document.querySelectorAll('li').forEach((e) => {
    //   e.onclick = function() {
    //     console.log(this.innerHTML)
    //   }
    // }) 




    //jq写法
        // $("ul").delegate("li","click",function(){
        //     $(this).css("background", "red");
        // });

        //  事件委托：ul>li*6
        // ul.on("click ",function(e){
        //     e = e || window.event 
        //     console.log(e.target.innerhtml)
        // })


        
    //比如这个，1秒创建一个按钮，就要用事件委托：    
        //     setInterval(function(){
        //     var btn = document.createElement('button');
        //     btn.innerHTML = '按我';
        //     document.body.appendChild(btn);
        // }, 1000);

        // document.body.onclick = function(e){
        //     if(e.target.nodeName.toLowerCase() === 'button'){
        //         e.target.style.background = 'red';
        //     }
        // }

//_________________________________________________________________________________________________________________________-
// 事件类型 
// 1. 鼠标类型                 //2. 键盘事件            //3. 表单事件                  //4. window事件
    //click(点击)                 //keydown(按下)           //focus(获取焦点)               //load(加载完成)
    //dbclick(双击)               //keypress(按压)          //blur(失去焦点)                //resize(尺寸发生改变)
    //mousedown(按下)             //keyup(抬起)             //input(监听输入)               //scroll(页面滚动)
    //mouseup(抬起)                                         //change(监听内容发生改变)
    //mousemove(移动)
    //mouseout(移出)
    //wheel(滚轮)
    //contextmenu(右键)



//补充
    /*
    mouseover 和 mouseenter 的区别？
        当鼠标移动到元素上时就会触发 mouseenter 事件，类似 mouseover，它们两者之间的差别是 mouseenter 不会冒泡。
        由于mouseenter不支持事件冒泡，导致在一个元素的子元素上进入或离开的时候会触发其mouseover和mouseout事件，但是却不会触发mouseenter和mouseleave 事件。   
    */


</script>